package com.jweb.framework.ws.soap.axiom;

import java.io.*;
import java.util.Iterator;
import java.util.Locale;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLInputFactory;
import org.apache.axiom.om.*;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.xml.namespace.QNameUtils;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.ls.*;

/**
 * 修改人： Thomas
 * 修改内容：新增 
 * 类说明：
 */
public abstract class AxiomUtils {
	
	public static OMNamespace toNamespace(QName qName, OMElement resolveElement) throws OMException {
        String prefix = QNameUtils.getPrefix(qName);
        if (StringUtils.hasLength(qName.getNamespaceURI()) && StringUtils.hasLength(prefix)) {
            return resolveElement.declareNamespace(qName.getNamespaceURI(), prefix);
        }
        else if (StringUtils.hasLength(qName.getNamespaceURI())) {
            // check for existing namespace, and declare if necessary
            return resolveElement.declareNamespace(qName.getNamespaceURI(), "");
        }
        else {
            throw new IllegalArgumentException("qName [" + qName + "] does not contain a namespace");
        }
    }
	
	public static String toLanguage(Locale locale) {
        return locale.toString().replace('_', '-');
    }
	
    public static Locale toLocale(String language) {
        language = language.replace('-', '_');
        return StringUtils.parseLocaleString(language);
    }
    
    /** Removes the contents (i.e. children) of the container. */
    public static void removeContents(OMContainer container) {
        for (Iterator<?> iterator = container.getChildren(); iterator.hasNext();) {
            iterator.next();
            iterator.remove();
        }
    }
    
    public static Document toDocument(SOAPEnvelope envelope) {
        try {
            if (envelope instanceof Element) {
                return ((Element) envelope).getOwnerDocument();
            }
            else {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                envelope.build();
                envelope.serialize(bos);

                ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
                DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
                documentBuilderFactory.setNamespaceAware(true);
                return documentBuilderFactory.newDocumentBuilder().parse(bis);
            }
        }
        catch (Exception ex) {
            throw new IllegalArgumentException("Error in converting SOAP Envelope to Document", ex);
        }
    }
    
    public static SOAPEnvelope toEnvelope(Document document) {
        try {
            DOMImplementation implementation = document.getImplementation();
            Assert.isInstanceOf(DOMImplementationLS.class, implementation);
           
            DOMImplementationLS loadSaveImplementation = (DOMImplementationLS) implementation;
           
            LSOutput output = loadSaveImplementation.createLSOutput();
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
           
            output.setByteStream(bos);
           
            LSSerializer serializer = loadSaveImplementation.createLSSerializer();
           
            serializer.write(document, output);

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());

            StAXSOAPModelBuilder stAXSOAPModelBuilder =
                    new StAXSOAPModelBuilder(XMLInputFactory.newInstance().createXMLStreamReader(bis), null);
            SOAPEnvelope envelope = stAXSOAPModelBuilder.getSOAPEnvelope();

            // Necessary to build a correct Axiom tree, see SWS-483
            envelope.serialize(new NullOutputStream());

            return envelope;
        }
        catch (Exception ex) {
            IllegalArgumentException iaex =
                    new IllegalArgumentException("Error in converting Document to SOAP Envelope");
            iaex.initCause(ex);
            throw iaex;
        }
    }
	
	
	
	
	 /** OutputStream that does nothing. */
    private static class NullOutputStream extends OutputStream {

        @Override
        public void write(int b) throws IOException {
        }

        @Override
        public void write(byte[] b) throws IOException {
        }

        @Override
        public void write(byte[] b, int off, int len) throws IOException {
        }
    }

}
